home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir30 / dt100.zip / XDOS_DT.C < prev    next >
C/C++ Source or Header  |  1993-08-28  |  27KB  |  790 lines

  1. /* XDOS_DT.C
  2.  
  3.    *************************************************
  4.    **** THIS SOURCE CODE IS DERIVED FROM XDOS.C ****
  5.    **** AND MODIFIED FOR USE WITH DRAFTOOLS.    ****
  6.    **** FUNCTION NAMES HAVE BEEN PREFIXED WITH  ****
  7.    **** 'DT_' TO AVOID ANY NAMING CONFLICTS.    ****
  8.    ****                                         ****
  9.    ****    Last Revision:  8/29/93              ****
  10.    *************************************************
  11.  
  12.     Copyright 1992 Autodesk, Inc.
  13.  
  14.     Permission to use, copy, modify, and distribute this software 
  15.     for any purpose and without fee is hereby granted, provided 
  16.     that the above copyright notice appears in all copies and that 
  17.     both that copyright notice and this permission notice appear in 
  18.     all supporting documentation.
  19.  
  20.     THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED
  21.     WARRANTY.  ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR
  22.     PURPOSE AND OF MERCHANTABILITY ARE HEREBY DISCLAIMED.
  23.  
  24.  
  25.  
  26.  
  27.     DESCRIPTION:
  28.     ============
  29.  
  30.     WatCom C/C++ 9.5 protected mode ADS application for use with AutoCAD
  31.     Release 12.
  32.  
  33.     Each function returns an ADS error for invalid, too few or too many
  34.     arguments.  Each function returns nil on failure, unless otherwise
  35.     noted.
  36.  
  37.     DT_DOSDIR ------------------------------------------------------------------
  38.  
  39.     Returns a list of file names in the current directory matching a given
  40.     wildcard.  The values in the list are returned as strings.  The mask
  41.     argument determines what type(s) of files are returned in the list.
  42.  
  43.     A mask of 0 will return all normal files in the current directory.
  44.     Note that this includes *read-only* files.
  45.  
  46.     Other mask arguments can be constructed as a bit-coded integer, using
  47.     the following codes:
  48.  
  49.          1: Read-only files
  50.          2: Hidden files
  51.          4: System files
  52.          8: Volume ID
  53.         16: Subdirectory
  54.         32: Archived
  55.  
  56.     A mask of 1 will return all the normal files and all the read-only files
  57.     in the current directory.
  58.  
  59.     Usage:      (dt_dosdir wild-card-string integer-mask)
  60.     Example:    (dt_dosdir "*.dwg" 0)
  61.  
  62.     DT_DOSSUBDIR ---------------------------------------------------------------
  63.  
  64.     Returns a list of sub-directories in the current directory.  The values
  65.     in the list are returned as strings.
  66.  
  67.     Usage:      (dt_dossubdir)
  68.  
  69.     DT_DOSDRV ------------------------------------------------------------------
  70.  
  71.     Returns a list of available drives.  The list is integer based, where 1
  72.     = Drive A:, 2 = Drive B:, 3 = Drive C:, etc.  The list may not be
  73.     sequential, i.e., the list (1 2 3 7 8) means that drives A:, B:, C:, G:
  74.     and H: are available.
  75.  
  76.     Usage:      (dt_dosdrv)
  77.  
  78.     DT_DOSCURDIR ---------------------------------------------------------------
  79.  
  80.     Returns the current directory as a string.
  81.  
  82.     Usage:      (dt_doscurdir)
  83.  
  84.     DT_DOSCURDRV ---------------------------------------------------------------
  85.  
  86.     Returns the current drive.  The return value is an integer, where 1 =
  87.     Drive A:, 2 = Drive B:, 3 = Drive C:, etc.
  88.  
  89.     Usage:      (dt_doscurdrv)
  90.  
  91.     DT_DOSSETDIR ---------------------------------------------------------------
  92.  
  93.     Changes the current directory matching a full pathname.  The pathname
  94.     argument must be a string.
  95.  
  96.     Usage:      (dt_dossetdir pathname-string)
  97.     Example:    (dt_dossetdir "\\r12\\sample")
  98.     Example:    (dt_dossetdir "/r12/sample")
  99.  
  100.     DT_DOSSETDRV ---------------------------------------------------------------
  101.  
  102.     Changes the current drive.  The single required argument must be an
  103.     integer, where 1 = Drive A:, 2 = Drive B:, 3 = Drive C:, etc.
  104.  
  105.     Usage:      (dt_dossetdrv drive-integer)
  106.     Example:    (dt_dossetdrv 3)               ;set to drive C:
  107.  
  108.     DT_DOSDELETEFILE -----------------------------------------------------------
  109.  
  110.     Deletes a file.  The filename argument must be a string, and can
  111.     include a full path specification.
  112.  
  113.     The file must be a read/write file; that is, the function will not
  114.     delete a file with a read-only attribute set true.
  115.  
  116.     Usage:      (dt_dosdeletefile pathname-string)
  117.     Example:    (dt_dosdeletefile "/work/junk.scr")
  118.  
  119.     DT_DOSRENAME ---------------------------------------------------------------
  120.  
  121.     This function renames one file to another file name. The function takes
  122.     two arguments. Each one has to be a file name or path to a file name.
  123.     The return value is an integer. A 1 means successful and a 0 means the
  124.     call failed.
  125.  
  126.     Usage:     (dt_dosrename pathname-string newpathname-string)
  127.                (dt_dosrename file-name newfile-name)
  128.  
  129.     Example:   (dt_dosrename "C:\\auto.exe" "aaa.exe")
  130.                (dt_dosrename "acad.exe" "daca.exe")
  131.  
  132. *****************************************************************************
  133. *   NOTE: Any file name not in current directory will be returned as an     *
  134. *         error unless the double back slashes are used in the path, as in  *
  135. *         the above examples. This applies to almost all functions in this  *
  136. *         file.                                                             *
  137. *****************************************************************************
  138.  
  139.    AUTHORS:
  140.             Josh Gordon,  Autodesk, Inc.
  141.             Brad Zehring, Autodesk, Inc.
  142.             Jerry A. Schwartz, PlotMasters, Inc.
  143.             Jonathan M. Schwartz, Interlake, Inc.
  144.  
  145.  
  146.     Modified to compile as a protected mode application for WatCom C/C++ 9.5
  147.   by:
  148.             Owen Wengerd, Manu-Soft Computer Services
  149.             P.O. Box 84
  150.             Fredericksburg, OH  44627
  151.             CompuServe ID:  71324,3252
  152. */
  153.  
  154. #include <stdio.h>
  155. #include <dos.h>
  156. #include <io.h>
  157. #include <fcntl.h>
  158. #include <stdlib.h>
  159. #include <adslib.h>
  160.  
  161. #define MAX_DIR 64
  162.  
  163. /* Utility definition to get an  array's  element  count  (at  compile
  164.    time).   For  example:  
  165.  
  166.        int  arr[] = {1,2,3,4,5};
  167.        ... 
  168.        printf("%d", ELEMENTS(arr));
  169.  
  170.    would print a five.  ELEMENTS("abc") can also be used to  tell  how
  171.    many  bytes are in a string constant INCLUDING THE TRAILING NULL. */
  172.  
  173. #define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
  174.  
  175. /* All the functions that we'll define will be listed in a single table,
  176.    together with the internal function that we call to handle each.  The
  177.    functions all take a single argument (the resbuf that has the
  178.    arguments) and return an integer (RTNORM or RTERROR for good or bad
  179.    status).  */
  180.  
  181. /* First, define the structure of the table: a string giving the AutoCAD name
  182.    of the function, and a pointer to a function returning type int. */
  183.  
  184. struct func_entry { char *func_name; int (*func) _((struct resbuf *)); };
  185.  
  186. /* Here we declare the functions that handle the calls. */
  187. int dt_dosdir      _((struct resbuf *rb));
  188. int dt_dossubdir   _((struct resbuf *rb));
  189. int dt_dosdrv      _((struct resbuf *rb));
  190. int dt_doscurdrv   _((struct resbuf *rb));
  191. int dt_dossetdrv   _((struct resbuf *rb));
  192. int dt_dossetdir   _((struct resbuf *rb));
  193. int dt_doscurdir   _((struct resbuf *rb));
  194. int dt_dosdeletefile  _((struct resbuf *rb));
  195. int dt_dosrename   _((struct resbuf *rb));
  196.  
  197. /* Here we define the array of function names and handlers. */
  198. static struct func_entry func_table[] = { {"dt_dosdir", dt_dosdir},
  199.                                           {"dt_dossubdir", dt_dossubdir},
  200.                                           {"dt_doscurdrv", dt_doscurdrv},
  201.                                           {"dt_dossetdrv", dt_dossetdrv},
  202.                                           {"dt_dosdrv", dt_dosdrv},
  203.                                           {"dt_dossetdir", dt_dossetdir},
  204.                                           {"dt_doscurdir", dt_doscurdir},
  205.                                           {"dt_dosdeletefile", dt_dosdeletefile},
  206.                                           {"dt_dosrename",dt_dosrename},
  207.                                         };
  208.  
  209. /* To add more functions to this table, just put them in the list, after
  210.    declaring the function names.  Note that in standard C it's all right to
  211.    have a superfluous comma after the last item.  */
  212.  
  213. /* The code from here to the end of dofun() is UNCHANGED when you add or delete
  214.    functions. */
  215.  
  216. /*  Declarations of other local functions  */
  217. void     main       _((int, char **));
  218. int      dofun      _((void));
  219. int      funcload   _((void));
  220. char *strdup(const char *src);
  221.  
  222. char *str_tolow(char *string);  /* converts string to all lowercase */
  223. char *str_toup(char *string);   /* converts string to all uppercase */
  224.  
  225. /*-----------------------------------------------------------------------*/
  226. /* MAIN - the main routine */
  227.  
  228. void main(argc,argv)
  229.   int argc;
  230.   char *argv[];
  231. {
  232.     short scode = RSRSLT;             /* Normal result code (default) */
  233.     int stat;
  234.  
  235.     ads_init(argc, argv);             /* Open communication with AutoLISP */
  236.  
  237.     for ( ;; ) {                      /* Request/Result loop */
  238.  
  239.         if ((stat = ads_link(scode)) < 0) {
  240.             printf("XDOS_DT: bad status from ads_link() = %d\n", stat);
  241.             fflush(stdout);
  242.             exit(1);
  243.         }
  244.  
  245.         scode = RSRSLT;               /* Reset result code */
  246.  
  247.         switch (stat) {
  248.  
  249.         case RQXLOAD:                 /* Load & define functions */
  250.             scode = funcload() == RTNORM ? RSRSLT : RSERR;
  251.             break;
  252.  
  253.         case RQSUBR:                  /* Handle external function requests */
  254.             scode = dofun() == RTNORM ? RSRSLT : RSERR;
  255.             break;
  256.  
  257.         default:
  258.             break;
  259.         }
  260.     }
  261. }
  262.  
  263. /*-----------------------------------------------------------------------*/
  264. /* FUNCLOAD  --  Define this application's external functions.  Return
  265.                  RTERROR on error, else RTNORM.                   */
  266.  
  267. static int funcload()
  268. {
  269.     int i;
  270.  
  271.     for (i = 0; i < ELEMENTS(func_table); i++) {
  272.         if (!ads_defun(func_table[i].func_name, i))
  273.             return RTERROR;
  274.     }
  275.     return RTNORM;
  276. }
  277.  
  278. /*-----------------------------------------------------------------------*/
  279. /* DOFUN -- Execute external function (called upon an RQSUBR request).  
  280.             Return value from the function executed, RTNORM or RTERROR. */
  281.  
  282. static int dofun()
  283. {
  284.     struct resbuf *rb;
  285.     int val;
  286.  
  287.     /* Get the function code and check that it's within range.
  288.        (It can't fail to be, but paranoia doesn't hurt.) */
  289.     if ((val = ads_getfuncode()) < 0 || val >= ELEMENTS(func_table)) {
  290.         ads_fail("Received nonexistent function code.");
  291.         return RTERROR;
  292.     }
  293.  
  294.     /* Fetch the arguments, if any. */
  295.     rb = ads_getargs();
  296.  
  297.     /* Call the handler and return its success-failure status. */
  298.     val = (*func_table[val].func)(rb);
  299.     ads_relrb(rb);
  300.     return val;
  301. }
  302.  
  303.  
  304. /* The code from the beginning of main() to here is UNCHANGED when you add or
  305.    delete functions.  */
  306.  
  307. /* we need our own strdup... */
  308.  
  309. char *strdup(const char *src)
  310. {
  311.     char *retval = NULL;
  312.  
  313.     /* If the malloc fails, bail out of here because there's something
  314.        horribly wrong with memory allocation */
  315.     if ((retval = malloc(strlen(src) + 1)) == NULL) {
  316.         ads_printf("\nmalloc failed in strdup, XDOS_DT.C");
  317.         ads_exit(1);
  318.     } else {
  319.         strcpy(retval, src);
  320.         return retval;
  321.     }
  322. }
  323.  
  324. /* Returns subdirectories under current directory to AutoLISP as a list of
  325.    strings.  
  326.  
  327.    getargs argument is a pointer to the first result buffer returned by
  328.    ads_getargs().  We expect to find no values in the resbuf chain.*/
  329.  
  330. int dt_dossubdir(getargs)
  331.   struct resbuf *getargs;
  332. {
  333.     struct resbuf *rb = NULL;         /* temp resbuf for loop */
  334.     struct find_t c_file;             /* MSC file structure   */
  335.     int retval;                       /* loop test            */
  336.     char *wildspec = "*.*";           /* test all files       */
  337.     unsigned mask = _A_SUBDIR;        /* subdirectory mask    */
  338.     unsigned int fileattrib;          /* file attribute       */
  339.     struct resbuf *retlist, *rettail; /* return list          */
  340.  
  341.     if (getargs != NULL) {
  342.         ads_printf("\nDT_DOSSUBDIR: Too many arguments.");
  343.         return RTERROR;
  344.     }
  345.  
  346.     /* Get first filename from current directory */
  347.     retval = _dos_findfirst(wildspec, mask, &c_file);
  348.  
  349.     retlist = NULL;
  350.     rettail = NULL;
  351.     while (retval == 0) {
  352.         _dos_getfileattr(c_file.name, &fileattrib);     /* get file's attr  */
  353.         if ((fileattrib & _A_SUBDIR) != 0) {            /* directory?       */
  354.  
  355.             rb = ads_newrb(RTSTR);    /* allocate new resbuf          */
  356.  
  357.             if (retlist == NULL) {    /* new return list?             */
  358.                 rettail = retlist = rb;     /* they're all the same         */
  359.             } else {                  /* else, point current tail to  */
  360.                 rettail->rbnext = rb; /* new resbuf and then set tail */
  361.                 rettail = rb;         /* equal to new resbuf          */
  362.             }
  363.             /* store filename in list   */
  364.             rb->resval.rstring = strdup(c_file.name);
  365.         }
  366.  
  367.         retval = _dos_findnext(&c_file);         /* get next filename */
  368.     }
  369.  
  370.     /* Now set up to return the list */
  371.     ads_retlist(retlist);
  372.     ads_relrb(retlist);
  373.     return RTNORM;
  374. }
  375.  
  376. /* Returns list of files in current drive and directory to AutoLISP as
  377.    a list of strings.
  378.  
  379.    getargs argument is a pointer to the first result buffer returned by
  380.    ads_getargs().  We expect to find two values in the resbuf chain: a
  381.    string wildcard specification and an integer file attribute mask.  */
  382.  
  383. int dt_dosdir(getargs)
  384.   struct resbuf *getargs;
  385. {
  386.     struct resbuf *rb = NULL;         /* temp resbuf for loop and args */
  387.     struct find_t c_file;             /* MSC file structure            */
  388.     int retval;                       /* loop test                     */
  389.     char *wildspec = NULL;            /* initialize wildcard spec      */
  390.     unsigned mask;                    /* file mask from user           */
  391.     struct resbuf *retlist, *rettail; /* return list                   */
  392.  
  393.     /* Get the arguments passed in with the function */
  394.     if (getargs == NULL) {
  395.         ads_printf("\nDT_DOSDIR: Expected argument.");
  396.         return RTERROR;
  397.     }
  398.  
  399.     rb = getargs;
  400.  
  401.     /* Get wildcard specification */
  402.     if (rb->restype != RTSTR) {
  403.         ads_printf("\nDT_DOSDIR called with a %d type.", rb->restype);
  404.         ads_printf("\nExpected a string as first argument.");
  405.         return RTERROR;
  406.     }
  407.  
  408.     /* Save the value in local */
  409.     wildspec = strdup(rb->resval.rstring);
  410.  
  411.     /* Advance to next argument */
  412.     rb = rb->rbnext;
  413.  
  414.     /* Get file attribute mask */
  415.     if (rb->restype != RTSHORT) {
  416.         ads_printf("\nDT_DOSDIR called with a %d type.", rb->restype);
  417.         ads_printf("\nExpected an integer as second argument.");
  418.         free(wildspec);                 /* free the string */
  419.         return RTERROR;
  420.     }
  421.  
  422.     /* Save the value in local */
  423.     mask = rb->resval.rint;
  424.  
  425.     /* Check for too many arguments */
  426.     if (rb->rbnext != NULL) {
  427.         ads_printf("\nDT_DOSDIR: Too many arguments.");
  428.         free (wildspec);                /* free the string */
  429.         return RTERROR;
  430.     }
  431.  
  432.     /* Get first filename from current directory */
  433.     retval = _dos_findfirst(wildspec, mask, &c_file);
  434.  
  435.     retlist = NULL;
  436.     rettail = NULL;
  437.     while (retval == 0) {
  438.  
  439.         rb = ads_newrb(RTSTR);        /* allocate new buffer         */
  440.  
  441.         if (retlist == NULL)          /* new return list?            */
  442.             rettail = retlist = rb;   /* they're all the same        */
  443.         else {                        /* else, point current tail to */
  444.             rettail->rbnext = rb;     /* new resbuf and then set tail*/
  445.             rettail = rb;             /*equal to new resbuf          */
  446.         }
  447.  
  448.         rb->resval.rstring = strdup(c_file.name); /* store filename in list */
  449.         retval = _dos_findnext(&c_file);          /* get next filename      */
  450.     }
  451.  
  452.     /* Now set up to return the list */
  453.     ads_retlist(retlist);
  454.     ads_relrb(retlist);
  455.     free (wildspec);                   /* free the string */
  456.     return RTNORM;
  457. }
  458.  
  459. /* dt_doscurdrv assumes we will always be able to get the current drive
  460.    by calling _dos_getdrive().  There is no error checking.  It returns
  461.    the drive number as an integer to AutoLISP.
  462.  
  463.    getargs argument is a pointer to the first result buffer returned by
  464.    ads_getargs().  We expect to find no values in the resbuf chain. */
  465.  
  466. int dt_doscurdrv(getargs)
  467.   struct resbuf *getargs;
  468. {
  469.     unsigned drive;                   /* current drive */
  470.  
  471.     if (getargs != NULL) {
  472.         ads_printf("\nDT_DOSCURDRV: Too many arguments.");
  473.         return RTERROR;
  474.     }
  475.  
  476.     _dos_getdrive(&drive);
  477.  
  478.     /* Now return the drive as an integer */
  479.     ads_retint(drive);
  480.  
  481.     return RTNORM;
  482. }
  483.  
  484. /* Sets new current drive.  Returns new drive as integer to AutoLISP.
  485.  
  486.    getargs argument is a pointer to the first result buffer returned by
  487.    ads_getargs().  We expect to find one value in the resbuf chain: an
  488.    integer corresponding to the drive that we make current. */
  489.  
  490. int dt_dossetdrv(getargs)
  491.   struct resbuf *getargs;
  492. {
  493.     unsigned newdrive;                /* drive argument from user       */
  494.     unsigned olddrive;                /* drive before attempt to change */
  495.     unsigned curdrive;                /* drive after attempt to change  */
  496.     unsigned number_of_drives;        /* required by _dos_setdrive()    */
  497.  
  498.     if (getargs == NULL) {
  499.         ads_printf("\nDT_DOSSETDRV: Expected an argument.");
  500.         return RTERROR;
  501.     }
  502.  
  503.     if (getargs->restype != RTSHORT) {
  504.         ads_printf("\nDT_DOSSETDRV called with a %d type.", getargs->restype);
  505.         ads_printf("\nExpected an integer.");
  506.         return RTERROR;
  507.     }
  508.  
  509.     newdrive = getargs->resval.rint;  /* get argument from user */
  510.  
  511.     _dos_getdrive(&olddrive);         /* store old drive */
  512.  
  513.     _dos_setdrive(newdrive, &number_of_drives); /* set to user's request */
  514.  
  515.     _dos_getdrive(&curdrive);         /* get current drive */
  516.  
  517.     if (curdrive != newdrive) {       /* if current drive not */
  518.         _dos_setdrive(olddrive, &number_of_drives); /* user's request, then */
  519.         ads_retnil();                 /* restore old drive    */
  520.         return RTNORM;                /* and return nil, else */
  521.     }
  522.  
  523.     ads_retint(curdrive);             /* return new drive     */
  524.     return RTNORM;
  525.  
  526. }
  527.  
  528. /* Returns the list of available drives to AutoLISP as a list of integers.
  529.  
  530.    getargs argument is a pointer to the first result buffer returned by
  531.    ads_getargs().  We expect to find no values in the resbuf chain.  */
  532.  
  533. int dt_dosdrv(getargs)
  534.   struct resbuf *getargs;
  535.  
  536. {
  537.     unsigned drive;                   /* loop variable for drive     */
  538.     unsigned set_drive;
  539.     unsigned olddrive;                /* store current drive         */
  540.     unsigned number_of_drives;        /* required by _dos_setdrive() */
  541.     struct resbuf *retlist, *rettail; /* return list                 */
  542.     struct resbuf *rb;
  543.  
  544.     if (getargs != NULL) {
  545.         ads_printf("\nDT_DOSDRV: Too many arguments.");
  546.         return RTERROR;
  547.     }
  548.  
  549.     /* Save current drive */
  550.     _dos_getdrive(&olddrive);
  551.  
  552.     retlist = NULL;
  553.     rettail = NULL;
  554.  
  555.     for (drive = 1; drive <= 26; drive++) {              /* 26 drives possible in DT_DOS */
  556.  
  557.         _dos_setdrive (drive, &number_of_drives);
  558.         _dos_getdrive (&set_drive);
  559.  
  560.         if (set_drive == drive) {                        /* if we can set to it,      */
  561.                                                          /* then the drive exists     */
  562.             rb = ads_newrb(RTSHORT);
  563.  
  564.             if (retlist == NULL)
  565.                 rettail = retlist = rb;
  566.             else {
  567.                 rettail->rbnext = rb;
  568.                 rettail = rb;
  569.             }
  570.  
  571.             rb->resval.rint = drive;  /* add it to the return list */
  572.         }
  573.     }
  574.  
  575.         /* Restore old drive */
  576.     _dos_setdrive(olddrive, &number_of_drives);
  577.  
  578.     /* Now set up to return the list */
  579.     ads_retlist(retlist);
  580.     ads_relrb(retlist);
  581.     return RTNORM;
  582. }
  583.  
  584. /* Sets the current directory and returns the current directory to AutoLISP
  585.    as a string.
  586.  
  587.    getargs argument is a pointer to the first result buffer returned by
  588.    ads_getargs().  We expect to find one argument in the resbuf chain: a
  589.    string for the directory that we make current. */
  590.  
  591. int dt_dossetdir(getargs)
  592.   struct resbuf *getargs;
  593. {
  594.     char *dirname;                    /* local for dir arg from user */
  595.  
  596.     if (getargs == NULL) {
  597.         ads_printf("\nDT_DOSSETDIR: Expected an argument.");
  598.         return RTERROR;
  599.     }
  600.  
  601.     if (getargs->restype != RTSTR) {
  602.         ads_printf("\nDT_DOSSETDIR called with a %d type.", getargs->restype);
  603.         ads_printf("\nExpected a string.");
  604.         return RTERROR;
  605.     }
  606.  
  607.     /* Store the directory in local */
  608.     dirname = strdup(getargs->resval.rstring);
  609.  
  610.     if (chdir(dirname)) {             /* if the call failed, then return nil */
  611.         free(dirname);                /* free the string */
  612.         ads_retnil();
  613.         return RTNORM;
  614.     }
  615.  
  616.     ads_retstr(dirname);              /* return the directory that we set to */
  617.     free(dirname);                    /* free the string */
  618.     return RTNORM;
  619.  
  620. }
  621.  
  622. /* dt_doscurdir assumes that we will always be able to get the current
  623.    directory with a _getcwd() call.  There's no error checking.
  624.  
  625.    Returns the current directory as a string to AutoLISP.
  626.  
  627.    getargs argument is a pointer to the first result buffer returned by
  628.    ads_getargs().  We expect to find no values in the resbuf chain.  */
  629.  
  630. int dt_doscurdir(getargs)
  631.   struct resbuf *getargs;
  632. {
  633.  
  634.     char buffer[MAX_DIR];             /* Buffer for maximum directory string */
  635.  
  636.     if (getargs != NULL) {
  637.         ads_printf("\nDT_DOSCURDIR: Too many arguments.");
  638.         return RTERROR;
  639.     }
  640.  
  641.     if ((getcwd(buffer, MAX_DIR)) == NULL) {  /* get the current directory */
  642.         free(buffer);                        /* if we fail, free the      */
  643.         ads_retnil();                        /* string and return nil     */
  644.         return RTNORM;
  645.     }
  646.  
  647.     ads_retstr(buffer);               /* return the directory */
  648.     free(buffer);                     /* free the string      */
  649.     return RTNORM;
  650.  
  651. }
  652.  
  653. /* Deletes a file.
  654.  
  655.    getargs argument is a pointer to the first result buffer returned by
  656.    ads_getargs().  We expect to find one value in the resbuf chain: a
  657.    string corresponding to the filename we will delete. */
  658.  
  659. int dt_dosdeletefile(getargs)
  660.   struct resbuf *getargs;
  661. {
  662.     struct resbuf *rb = NULL;         /* temp resbuf for args          */
  663.     char *filespec = NULL;            /* initialize filename spec      */
  664.  
  665.     /* Get the arguments passed in with the function */
  666.     if (getargs == NULL) {
  667.         ads_printf("\nDT_DOSDELETEFILE: Expected argument.");
  668.         return RTERROR;
  669.     }
  670.  
  671.     rb = getargs;
  672.  
  673.     /* Get file specification */
  674.     if (rb->restype != RTSTR) {
  675.         ads_printf("\nDT_DOSDELETEFILE called with a %d type.", rb->restype);
  676.         ads_printf("\nExpected a string.");
  677.         return RTERROR;
  678.     }
  679.  
  680.     /* Save the value in local */
  681.     filespec = strdup(rb->resval.rstring);
  682.  
  683.     /* Check for too many arguments */
  684.     if (rb->rbnext != NULL) {
  685.         ads_printf("\nDT_DOSDELETEFILE: Too many arguments.");
  686.         free(filespec);                     /* free the string */
  687.         return RTERROR;
  688.     }
  689.  
  690.     if (remove(filespec) == -1) {               /* if we can't remove it */
  691.         ads_retnil();                           /* return nil and        */
  692.         free(filespec);                         /* free the string       */
  693.         return RTNORM;    
  694.     }
  695.  
  696.     ads_retstr(filespec);             /* return the deleted filename */
  697.     free(filespec);                   /* free the string             */
  698.     return RTNORM;
  699. }
  700.  
  701.  
  702. /* DT_DOSRENAME function is used to rename a file to another specified name
  703.    the function takes as two arguments two file names or two paths to file
  704.    names. Path names must conform to proper dos paths. The two arguments
  705.    are used to rename a file. The 1st arg. is the file to rename and the
  706.    2nd arg. is the name to rename the file to. The function returns a 1 if
  707.    successful and a 0 if failed.
  708. */
  709.  
  710. int dt_dosrename(getargs)
  711.     struct resbuf *getargs;
  712. {
  713.  char *fileold,*filenew;
  714.  int retval;
  715.  
  716.  if(getargs == NULL)   /* if no arguments passed */
  717.  {
  718.   ads_printf("\nDT_DOSRENAME: Expected an argument.");
  719.   return RTERROR;   /* if no args return an error */
  720.  }
  721.  
  722.  if(getargs->restype != RTSTR) /* if passed arg is not string return error */
  723.  {
  724.   ads_printf("\nDT_DOSRENAME: Called with a %d type.",getargs->restype);
  725.   ads_printf("\n1st parameter expected a string argument.");
  726.   return RTERROR;
  727.  }
  728.  
  729.  if(getargs->rbnext->restype != RTSTR) /* if passed arg is not string return error */
  730.  {
  731.   ads_printf("\nDT_DOSRENAME: Called with a %d type.",getargs->restype);
  732.   ads_printf("\n2nd parameter expected a string argument.");
  733.   return RTERROR;
  734.  }
  735.  
  736.  if(getargs->rbnext->rbnext != NULL) /* if too many arguments */
  737.  {
  738.   ads_printf("\nDT_DOSRENAME: Called with two many arguments.");
  739.   return RTERROR;
  740.  }
  741.  /* copy file path specs into temporay variables */
  742.  fileold = strdup(getargs->resval.rstring);
  743.  filenew = strdup(getargs->rbnext->resval.rstring);
  744.  
  745.  retval = rename(fileold,filenew);  /* rename file to new path */
  746.  
  747.  free(fileold);     /* free temporary storage for file specs */
  748.  free(filenew);
  749.  if(retval == 0)
  750.  {
  751.   ads_retint(1);
  752.  }
  753.  else
  754.  {
  755.  ads_retint(0);
  756.  }
  757.  return RTNORM;
  758. }
  759.  
  760.  
  761. char *str_toup(char *string)
  762. {
  763.  int index;
  764.  /* process string until null character found */
  765.  for(index = 0; *(string + index) != '\0';++index)
  766.  {
  767.   if( isalpha(*(string + index)) ) /* if alphabetic proceed */
  768.   {
  769.    *(string + index) = toupper(*(string + index));
  770.   /* if lower convert it, else leave alone */
  771.   }
  772.  }
  773.  return string;  /* return a pointer to the string */
  774. }
  775.  
  776. char *str_tolow(char *string)
  777. {
  778.  int index;
  779.  /* process string until null character found */
  780.  for(index = 0; *(string + index) != '\0';++index)
  781.  {
  782.   if( isalpha(*(string + index)) ) /* if alphabetic proceed */
  783.   {
  784.    *(string + index) = tolower(*(string + index));
  785.    /* if upper convert it, else leave alone */
  786.   }
  787.  }
  788.  return string;  /* return a pointer to the string */
  789. }
  790.